package com.yixing.tech.wms.service.impl;

import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.enums.YesOrNo;
import com.yixing.tech.common.service.AbstractWmsService;
import com.yixing.tech.wms.constant.WmsConstants;
import com.yixing.tech.wms.service.WmsTaskService;
import com.yixing.tech.wms.stock.out.StockOutConstants;
import com.yixing.tech.wms.stock.out.domain.Task;
import com.yixing.tech.common.vo.s3.UserVO;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.ConvertOperators;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.*;

/**
 * @author yixing tech
 * @since 1.0.0
 */
@Service
public class WmsTaskServiceImpl extends AbstractWmsService implements WmsTaskService {
    /**
     * 保存任务信息
     *
     * @param task 需保存的任务信息
     */
    @Override
    public Map<String, Object> saveTaskInfo(Task task) throws BusinessException {
        Map<String, Object> taskMap = new HashMap<>();
        taskMap.put("taskCode", task.getTaskCode());
        taskMap.put("taskType", ObjectUtils.isNotEmpty(task.getTaskType()) ?
                Document.parse(String.format("{id: ObjectId(\"%s\")}", task.getTaskType())) : "");
        taskMap.put("startLoc", task.getStartLoc());
        taskMap.put("endLoc", task.getEndLoc());
        taskMap.put("startArea", task.getStartArea());
        taskMap.put("endArea", task.getEndArea());
        taskMap.put("podCode", task.getPodCode());
        taskMap.put("status", Document.parse(String.format("{id: ObjectId(\"%s\")}", WmsConstants.DataStatus.VALID)));
        taskMap.put("performStatus", Document.parse(String.format("{id: ObjectId(\"%s\")}", WmsConstants.TaskPerformStatus.UNISSUED)));
        taskMap.put("priority", ObjectUtils.isEmpty(task.getPriority()) ? 3 : task.getPriority());
        taskMap.put("operationNo", task.getOperationNo());
        taskMap.put("business", task.getBusiness());

        if (ObjectUtils.isNotEmpty(RequestContextHolder.getRequestAttributes())) {
            UserVO userVO = getApiUser();

            taskMap.put("dispatcher", userVO.getName());
            taskMap.put("dispatchTime", new Date());

            taskMap.put("createId", userVO.getId());
            taskMap.put("createName", userVO.getName());
            taskMap.put("tenantId", userVO.getTenantId());
        }

        taskMap.put("isDelete", YesOrNo.NO.ordinal());
        taskMap.put("createTime", new Date());

        return mongoTemplate.save(taskMap, WmsConstants.TASK_TEMPLATE);
    }

    @Override
    public Task findTaskByTaskCode(String taskCode) {
        List<AggregationOperation> operations = new ArrayList<>();
        operations.add(Aggregation.match(Criteria.where("tenantId").is(tenantId).and("isDelete").ne(YesOrNo.YES.ordinal())
                .and("taskCode").is(taskCode)));
        operations.add(Aggregation.addFields()
                .addFieldWithValue("taskType", ConvertOperators.ToString.toString("$taskType.id"))
                .addFieldWithValue("status", ConvertOperators.ToString.toString("$status.id"))
                .addFieldWithValue("performStatus", ConvertOperators.ToString.toString("$performStatus.id"))
                .build());

        AggregationResults<Task> results = mongoTemplate.aggregate(Aggregation.newAggregation(operations), StockOutConstants.TASK_TEMPLATE, Task.class);
        return ObjectUtils.isNotEmpty(results.getMappedResults()) ? results.getMappedResults().get(0): null;
    }
}
